package com.cwd.arm.application.service.write;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.cwd.arm.application.dto.project.ProjectAddDto;
import com.cwd.arm.application.dto.project.ProjectUpdateDto;
import com.cwd.arm.application.dto.receiveNode.ReceiveNodeAddDto;
import com.cwd.arm.application.service.write.facade.ProjectWriteService;
import com.cwd.arm.application.service.write.facade.ReceiveNodeWriteService;
import com.cwd.arm.domain.entity.ProjectEntity;
import com.cwd.arm.domain.repository.ProjectRepository;
import com.cwd.arm.infrastructure.dao.ProjectReceiveDirectorDao;
import com.cwd.arm.infrastructure.dao.UserDao;
import com.cwd.arm.infrastructure.po.ProjectReceiveDirectorPo;
import com.cwd.arm.infrastructure.po.UserPo;
import org.apache.commons.collections.ListUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * Description:项目
 * Created on 2021年11月16日
 *
 * @author yan
 */
@Repository
@Primary
public class ProjectWriteServiceImpl implements ProjectWriteService {

    @Autowired
    private ProjectRepository projectRepository;

    @Autowired
    private ReceiveNodeWriteService receiveNodeWriteService;

    @Autowired
    private ProjectReceiveDirectorDao projectReceiveDirectorDao;

    @Autowired
    private UserDao userDao;

    @Transactional
    @Override
    public Long save(ProjectAddDto addDto) {
        ProjectEntity projectEntity = convertToEntity(addDto);
        Long projectId = projectRepository.save(projectEntity);
        List<Long> receiveDirectorIdList = addDto.getReceiveDirectorIdList();
        saveReceiveDirector(projectId, receiveDirectorIdList);
        addDto.setReceiveDirector(getReceiveDirectorShowName(receiveDirectorIdList));
        List<ReceiveNodeAddDto> receiveNodeAddDtoList = addDto.getReceiveNodeAddList();
        if (CollectionUtils.isNotEmpty(receiveNodeAddDtoList)) {
            addDto.setId(projectId);
            for (ReceiveNodeAddDto receiveNodeAddDto : receiveNodeAddDtoList) {
                receiveNodeAddDto.setProjectId(projectId);
            }
            receiveNodeWriteService.save(addDto);
        }
        return projectId;
    }

    @Transactional
    @Override
    public void update(ProjectUpdateDto updateDto) {
        List<Long> receiveDirectorIdList = updateDto.getReceiveDirectorIdList();
        updateReceiveDirector(updateDto.getId(), receiveDirectorIdList);
        updateDto.setReceiveDirector(getReceiveDirectorShowName(receiveDirectorIdList));
        projectRepository.update(convertToEntity(updateDto));
    }

    @Transactional
    @Override
    public void del(Long id) {
        projectReceiveDirectorDao.delByProjectId(id);
        projectRepository.del(id);
    }

    private ProjectEntity convertToEntity(ProjectAddDto dto) {
        ProjectEntity entity = new ProjectEntity();
        entity.setProjectTypeKey(dto.getProjectType());
        BeanUtils.copyProperties(dto, entity);
        return entity;
    }

    private ProjectEntity convertToEntity(ProjectUpdateDto dto) {
        ProjectEntity entity = new ProjectEntity();
        entity.setProjectTypeKey(dto.getProjectType());
        BeanUtils.copyProperties(dto, entity);
        return entity;
    }

    private void saveReceiveDirector(Long projectId, List<Long> receiveDirectorIdList) {
        if (CollectionUtils.isNotEmpty(receiveDirectorIdList)) {
            for (Long id : receiveDirectorIdList) {
                ProjectReceiveDirectorPo receiveDirectorPo = new ProjectReceiveDirectorPo();
                receiveDirectorPo.setProjectId(projectId);
                receiveDirectorPo.setReceiveDirectorId(id);
                projectReceiveDirectorDao.save(receiveDirectorPo);
            }
        }
    }

    private void updateReceiveDirector(Long projectId, List<Long> receiveDirectorIdList) {
        if (CollectionUtils.isNotEmpty(receiveDirectorIdList)) {
            List<ProjectReceiveDirectorPo> oldPoList = projectReceiveDirectorDao.selectListByProjectId(projectId);
            if(CollectionUtils.isEmpty(oldPoList)){
                saveReceiveDirector(projectId,receiveDirectorIdList);
            }else if(!isTheSameReceiveDirector(oldPoList,receiveDirectorIdList)){
                projectReceiveDirectorDao.delByProjectId(projectId);
                saveReceiveDirector(projectId,receiveDirectorIdList);
            }
        }
    }

    private boolean isTheSameReceiveDirector(List<ProjectReceiveDirectorPo> oldPoList,List<Long> receiveDirectorIdList){
        List<Long> oldReceiveDirectorIdList = oldPoList.stream().map(ProjectReceiveDirectorPo::getReceiveDirectorId).collect(Collectors.toList());
        return ListUtils.isEqualList(oldReceiveDirectorIdList,receiveDirectorIdList);
    }

    private String getReceiveDirectorShowName(List<Long> receiveDirectorIdList){
        String receiveDirector = null;
        if(CollectionUtils.isNotEmpty(receiveDirectorIdList)){
            UserPo userPo = userDao.getById(receiveDirectorIdList.get(0));
            receiveDirector = userPo.getUsername();
            if(StringUtils.isNotEmpty(userPo.getRealName())){
                receiveDirector = userPo.getRealName();
            }
            if(receiveDirectorIdList.size() > 1){
                receiveDirector = receiveDirector+"等";
            }
        }
        return receiveDirector;
    }

}
